#pragma once
#include <iostream>
#include <memory>


using namespace std;

//接收者类Television
class Television{
public:
	void open(){
		cout << "打开电视机!" << endl;
	}
	
	void close(){
		cout << "关闭电视机!" << endl; 
	} 
	
	void changeChannel(){
		cout << "切换电视频道!" << endl;
	}
};


//抽象命令类AbstartCommand
class AbstractCommand{
public:
	virtual void execute() = 0;
}; 

//具体命令类TVOpenCommand
class TVOpenCommand : public AbstractCommand{
public:
	TVOpenCommand(shared_ptr<Television> tv){
		this->tv = tv;
	}
	
	void execute(){
		tv->open();
	}
	
private:
	shared_ptr<Television> tv;
}; 


//具体命令类TVCloseCommmand
 class TVCloseCommand : public AbstractCommand{
public:
	TVCloseCommand(shared_ptr<Television> tv){
		this->tv = tv;
	}
	
	void execute(){
		tv->close();
	}
	
private:
	shared_ptr<Television> tv;
}; 

//具体命令类TVChangeCommmand
 class TVChangeCommand : public AbstractCommand{
public:
	TVChangeCommand(shared_ptr<Television> tv){
		this->tv = tv;
	}
	
	void execute(){
		tv->changeChannel();
	}
	
private:
	shared_ptr<Television> tv;
}; 


//调用者类Controller
class Controller{
public:
	Controller(shared_ptr<AbstractCommand> openCommand,
                   shared_ptr<AbstractCommand> closeCommand,
                   shared_ptr<AbstractCommand> changeCommand){
		this->openCommand = openCommand;
		this->closeCommand = closeCommand;
		this->changeCommand = changeCommand;
	}
	
	void open(){
		openCommand->execute();
	}
	
	void change(){
		changeCommand->execute();
	}
	
	void close(){
		closeCommand->execute();
	}
private:
	shared_ptr<AbstractCommand> openCommand;
	shared_ptr<AbstractCommand> closeCommand;
	shared_ptr<AbstractCommand> changeCommand;
}; 